#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(){
  //c接口(用户级)
  //c接口的文件操作返回值是FILE
  printf("hello printf\n");
  fprintf(stdout,"hello fprintf\n");
  fputs("hello puts\n",stdout);//往标准输出流中输出数据

  //系统级
  const char* msg = "hello write\n";
  write(1,msg,strlen(msg));
  
  fork();//凡是c语言的接口写到文件中，都写了2次，这是为什么呢？
  //代码结束之前，进行了创建子进程。
  //1：如果我们没有使用>（重定向输出),那么我们看到了4条信息
  //因为stdout使用的是行刷新，在进程fork之前，3条c函数已经将数据进行打印输出到显示器上了，这样的话，你的FILE内部，进程内部就不存在数据了。因为\n是换行。
  //如果前面的c接口没有加上换行符号，那么也会打印2遍，因为缓冲区没有刷新，而是等进程结束了才刷新的
  
  //2：如果我们进行了>(重定向输出)到文件log中，那么写入文件不再是显示器，而是普通文件，采用的刷新策略是全缓冲，之前的3条c函数，虽然带了换行，但是不足以
  //把缓冲区写满，数据并没有刷新。
  //执行fork的时候，stdout是属于父进程的，创建子进程的时候，紧接着就是进程退出了，谁先退出，一定会进行缓冲区刷新
  //通过写时拷贝，数据最后会显示2份。
  //这里的写时拷贝，是子进程创建出来，会拷贝父进程的代码段，数据段，堆栈等，这个时候父进程的数据段里面的代码已经写到了缓冲区里面，
  //这时候子进程进行拷贝，就不能再继续往同样的空间里面写入，所以就发生了写时拷贝，那么子进程的缓冲区里面也就有了父进程c接口的数据
  //所以就打印了2份c接口的数据，



  //3：write为什么没有显示2次呢？上面的过程都和write无关，write没有FILE，他的返回值是fd，就没有c提供的缓冲区。
   
  


  return 0;
}
